﻿using AutoMapper;
using Microsoft.AspNetCore.Http;
using RbacPermissionManage.Application.Admins.Dto;
using RbacPermissionManage.Application.Menus.Dto;
using RbacPermissionManage.Common;
using RbacPermissionManage.DoMain;
using RbacPermissionManage.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace RbacPermissionManage.Application.Menus
{
    public class MenuServices : IMenuServices
    {
        private readonly IRepository<Menu> repository;
        private readonly IMapper mapper;

        public MenuServices(IRepository<Menu> repository, IMapper mapper)
        {
            this.repository = repository;
            this.mapper = mapper;
        }

        /// <summary>
        /// 添加菜单
        /// </summary>
        /// <param name="createDto"></param>
        /// <returns></returns>
        public async Task<ResultDto> CreateAsync(MenuCreateDto createDto)
        {
            //查菜单名称
            var isExists = await repository.FirstOrDefaultAsync(x => x.MenuName == createDto.MenuName);
            if (isExists != null)
            {
                return new ResultDto { Code = Code.Failed, Message = "菜单名称已使用" };
            }

            Menu menu = mapper.Map<MenuCreateDto, Menu>(createDto);


            try
            {
                await repository.InsertAsync(menu);//调仓储的添加方法
                return new ResultDto { Code = Code.Success };
            }
            catch (Exception e)
            {
                return new ResultDto { Code = Code.Failed, Message = e.Message };
            }
        }


        /// <summary>
        /// 获取结点信息
        /// </summary>
        /// <returns></returns>
        public async Task<ResultDto<List<TreeDto>>> GetNodesAsync(SearchDto searchDto)
        {
            var list = await repository.QueryAsync();
            if (!string.IsNullOrEmpty(searchDto.Keywords))
            {
                list = list.Where(x => x.MenuName.Contains(searchDto.Keywords)).ToList();
            }
            return new ResultDto<List<TreeDto>> { Code = Code.Success, Data = GetTreeDtos(list, 0) };
        }

        /// <summary>
        /// 递归方法
        /// </summary>
        /// <param name="menus"></param>
        /// <param name="ParentId"></param>
        /// <returns></returns>
        private List<TreeDto> GetTreeDtos(List<Menu> menus, int ParentId)
        {
            List<TreeDto> treeDtos = new List<TreeDto>();
            var list = menus.Where(x => x.ParentId == ParentId);
            foreach (var item in list)
            {
                TreeDto treeDto = mapper.Map<Menu, TreeDto>(item);
                treeDto.Children = GetTreeDtos(menus, item.MenuId);
                if(!treeDto.Children.Any())
                {
                    treeDto.Children = null;
                }
                treeDtos.Add(treeDto);
            }
            return treeDtos;
        }

        /// <summary>
        /// 根据Id获取adminDto
        /// </summary>
        /// <param name="AdminId">管理员Id</param>
        /// <returns></returns>
        public async Task<ResultDto<TreeDto>> BackfillAsync(int MenuId)
        {
            var menu = await repository.FindAsync(MenuId);
            return new ResultDto<TreeDto> { Code = Code.Success, Data = mapper.Map<Menu, TreeDto>(menu) };
        }

        /// <summary>
        /// 修改菜单
        /// </summary>
        /// <param name="updateDto"></param>
        /// <returns></returns>
        public async Task<ResultDto> UpdateAsync(MenuUpdateDto updateDto)
        {
            //查用户名
            var isExists = await repository.FirstOrDefaultAsync(x => x.MenuName == updateDto.MenuName && x.MenuId != updateDto.MenuId);
            if (isExists != null)
            {
                return new ResultDto { Code = Code.Failed, Message = "菜单名称已使用" };
            }
            Menu entity = await repository.FindAsync(updateDto.MenuId);
            Menu menu = mapper.Map(updateDto, entity);


            try
            {
                await repository.UpdateAsync(entity);
                return new ResultDto { Code = Code.Success };
            }
            catch (Exception e)
            {
                return new ResultDto { Code = Code.Failed, Message = e.Message };
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="MenuId"></param>
        /// <returns></returns>
        public async Task<ResultDto<bool>> DeleteAsync(int MenuId)
        {
            try
            {
                var son = await repository.FirstOrDefaultAsync(x => x.ParentId == MenuId);
                if(son != null)
                {
                    return new ResultDto<bool> { Code = Code.Failed, Data = false, Message = "有子类不能删除" };
                }
                await repository.DeleteAsync(MenuId);
                return new ResultDto<bool> { Code = Code.Success, Data = true };
            }
            catch (Exception e)
            {
                return new ResultDto<bool> { Code = Code.Failed, Data = false, Message = e.Message };
                throw;
            }
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="menuIds"></param>
        /// <returns></returns>
        public async Task<ResultDto<bool>> BatchDelAsync(List<int> menuIds)
        {
            try
            {
                await repository.DeleteAsync(menuIds);
                return new ResultDto<bool> { Code = Code.Success, Data = true };
            }
            catch (Exception e)
            {
                return new ResultDto<bool> { Code = Code.Failed, Data = false, Message = e.Message };
                throw;
            }
        }
    }
}
